package JDBC;


import java.sql.Connection;
import java.sql.SQLException;
import java.util.Objects;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;


public class JDBCpool implements Pool {

    //空闲连接池
    private LinkedBlockingQueue<Connection> IdlePool;
    //活跃连接池
    private LinkedBlockingQueue<Connection> busyPool;
    //正在被使用的连接池
    private AtomicInteger activeSize = new AtomicInteger(0);
    private final int initSize = 10;//初始连接数为10个

    //最大连接数
    private final int maxSize;

    public JDBCpool(int maxSize) {
        this.maxSize = maxSize;
        init();
    }

    /**
     * 初始化连接池
     */
    @Override
    public void init() {
        IdlePool = new LinkedBlockingQueue<>();
        busyPool = new LinkedBlockingQueue<>();
        Connection connection = null;
        for (int i = 0;i<initSize;i++){
            try {
                connection = JDPCUtil.createConn();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        Objects.requireNonNull(connection,"连接不能为空"+getClass().getName());
        IdlePool.offer(connection);
    }

    /**
     * 获取连接,从空闲池中取出,放入活跃池中
     *
     * @return
     */
    @Override
    public Connection getConnection() {
        Connection connection = IdlePool.poll();
        if (null != connection) {
            busyPool.offer(connection);
            System.out.println("连接已经获取........");
            return connection;
        }
        //正在被使用的连接数与最大连接数比较
        if (activeSize.get() < maxSize) {
            if (activeSize.incrementAndGet() <= maxSize) {
                // 新创建一个连接
                try {
                   connection = JDPCUtil.getConnection();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                busyPool.offer(connection);
                return connection;
            }
        }
        //如果达到最大的连接数,就进入等待
        else {
            try {
                System.out.println("当前连接爆满,请等待........");
                connection = IdlePool.poll(10000, TimeUnit.MILLISECONDS);
                if (null == connection){
                    System.out.println("等待连接超时.....");
                    throw new RuntimeException("Time out");
                }
                System.out.println("新对象来了");
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        return connection;
    }

    /**
     * 释放连接,从活跃池取出,放入空闲池
     * @param conn
     */
    @Override
    public void release(Connection conn) {
        busyPool.remove(conn);
        IdlePool.offer(conn); // 添加一个
    }

    public void check(){
        for (int i=0;i<activeSize.get();i++) {
            Connection conn = IdlePool.poll();
            try {
                boolean valid = conn.isValid(2000);
                if (!valid) {
                    conn = JDPCUtil.getConnection();
                }
                IdlePool.offer(conn);
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 销毁连接
     */
    @Override
    public void detory() {
        IdlePool = null;
        busyPool = null;
    }

    public static void main(String[] args) {
        JDBCpool J = new JDBCpool(20);
        J.getConnection();
    }
}
